<template>
  <div class="system-config-page">
    <!-- 页面标题 -->
    <div class="page-header">
      <h2>系统配置管理</h2>
      <div class="header-actions">
        <el-button type="primary" @click="showImportDialog = true">
          <el-icon><Upload /></el-icon>
          导入配置
        </el-button>
        <el-button @click="exportConfigs">
          <el-icon><Download /></el-icon>
          导出配置
        </el-button>
        <el-button type="success" @click="showCreateDialog = true">
          <el-icon><Plus /></el-icon>
          新增配置
        </el-button>
      </div>
    </div>

    <!-- 搜索和筛选 -->
    <el-card class="search-card">
      <el-form :model="searchForm" :inline="true">
        <el-form-item label="配置分类">
          <el-select v-model="searchForm.category" placeholder="选择分类" clearable>
            <el-option
              v-for="category in categoryOptions"
              :key="category.value"
              :label="category.label"
              :value="category.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="配置分组">
          <el-select v-model="searchForm.group" placeholder="选择分组" clearable>
            <el-option
              v-for="group in groupOptions"
              :key="group.value"
              :label="group.label"
              :value="group.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="关键字">
          <el-input
            v-model="searchForm.keyword"
            placeholder="搜索配置键或名称"
            clearable
            style="width: 200px"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="loadConfigs">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 配置列表 -->
    <el-card class="config-table-card">
      <el-table
        v-loading="loading"
        :data="configList"
        border
        :height="tableHeight"
      >
        <el-table-column prop="config_key" label="配置键" width="200" fixed="left" />
        <el-table-column prop="display_name" label="显示名称" width="150" />
        <el-table-column prop="config_category" label="分类" width="120">
          <template #default="{ row }">
            <el-tag :type="getCategoryTagType(row.config_category)">
              {{ getCategoryLabel(row.config_category) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="config_type" label="类型" width="100">
          <template #default="{ row }">
            <el-tag type="info" size="small">
              {{ getTypeLabel(row.config_type) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="config_value" label="配置值" width="200">
          <template #default="{ row }">
            <span v-if="row.is_sensitive">***</span>
            <span v-else>{{ formatConfigValue(row.config_value, row.config_type) }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="group_name" label="分组" width="120" />
        <el-table-column prop="description" label="描述" min-width="200" show-overflow-tooltip />
        <el-table-column label="状态" width="100">
          <template #default="{ row }">
            <el-tag v-if="row.is_required" type="danger" size="small">必需</el-tag>
            <el-tag v-if="row.is_readonly" type="warning" size="small">只读</el-tag>
            <el-tag v-if="row.is_sensitive" type="info" size="small">敏感</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200" fixed="right">
          <template #default="{ row }">
            <el-button
              type="primary"
              size="small"
              @click="editConfig(row)"
            >
              编辑
            </el-button>
            <el-button
              type="info"
              size="small"
              @click="viewHistory(row)"
            >
              历史
            </el-button>
            <el-button
              v-if="!row.is_readonly"
              type="danger"
              size="small"
              @click="deleteConfig(row)"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination-wrapper">
        <el-pagination
          v-model:current-page="pagination.page"
          v-model:page-size="pagination.size"
          :total="pagination.total"
          :page-sizes="[20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="loadConfigs"
          @current-change="loadConfigs"
        />
      </div>
    </el-card>

    <!-- 新增/编辑配置对话框 -->
    <el-dialog
      v-model="showCreateDialog"
      :title="editingConfig ? '编辑配置' : '新增配置'"
      width="600px"
      @close="resetConfigForm"
    >
      <el-form
        ref="configFormRef"
        :model="configForm"
        :rules="configFormRules"
        label-width="120px"
      >
        <el-form-item label="配置键" prop="config_key">
          <el-input
            v-model="configForm.config_key"
            :disabled="!!editingConfig"
            placeholder="请输入配置键"
          />
        </el-form-item>
        <el-form-item label="显示名称" prop="display_name">
          <el-input v-model="configForm.display_name" placeholder="请输入显示名称" />
        </el-form-item>
        <el-form-item label="配置分类" prop="config_category">
          <el-select v-model="configForm.config_category" placeholder="选择分类">
            <el-option
              v-for="category in categoryOptions"
              :key="category.value"
              :label="category.label"
              :value="category.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="配置类型" prop="config_type">
          <el-select v-model="configForm.config_type" placeholder="选择类型">
            <el-option
              v-for="type in typeOptions"
              :key="type.value"
              :label="type.label"
              :value="type.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="配置值" prop="config_value">
          <el-input
            v-if="configForm.config_type === 'string' || configForm.config_type === 'password'"
            v-model="configForm.config_value"
            :type="configForm.config_type === 'password' ? 'password' : 'text'"
            placeholder="请输入配置值"
          />
          <el-input-number
            v-else-if="configForm.config_type === 'number'"
            v-model="configForm.config_value"
            style="width: 100%"
          />
          <el-switch
            v-else-if="configForm.config_type === 'boolean'"
            v-model="configForm.config_value"
          />
          <el-upload
            v-else-if="configForm.config_type === 'file'"
            action="/api/v1/upload"
            :show-file-list="false"
            :on-success="handleFileUpload"
          >
            <el-button type="primary">选择文件</el-button>
          </el-upload>
          <el-input
            v-else-if="configForm.config_type === 'json'"
            v-model="configForm.config_value"
            type="textarea"
            :rows="4"
            placeholder="请输入JSON格式配置"
          />
        </el-form-item>
        <el-form-item label="分组名称" prop="group_name">
          <el-input v-model="configForm.group_name" placeholder="请输入分组名称" />
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input
            v-model="configForm.description"
            type="textarea"
            :rows="3"
            placeholder="请输入配置描述"
          />
        </el-form-item>
        <el-form-item label="验证规则" prop="validation_rule">
          <el-input v-model="configForm.validation_rule" placeholder="正则表达式验证规则" />
        </el-form-item>
        <el-form-item label="排序顺序" prop="sort_order">
          <el-input-number v-model="configForm.sort_order" :min="0" :max="999" />
        </el-form-item>
        <el-form-item label="配置选项">
          <el-checkbox v-model="configForm.is_required">必需</el-checkbox>
          <el-checkbox v-model="configForm.is_readonly">只读</el-checkbox>
          <el-checkbox v-model="configForm.is_sensitive">敏感</el-checkbox>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showCreateDialog = false">取消</el-button>
        <el-button type="primary" @click="saveConfig">确定</el-button>
      </template>
    </el-dialog>

    <!-- 导入配置对话框 -->
    <el-dialog v-model="showImportDialog" title="导入配置" width="500px">
      <el-upload
        ref="uploadRef"
        :auto-upload="false"
        :limit="1"
        accept=".json"
        drag
        @change="handleFileChange"
      >
        <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
        <div class="el-upload__text">
          将文件拖到此处，或<em>点击上传</em>
        </div>
        <template #tip>
          <div class="el-upload__tip">
            只能上传 JSON 文件，且文件大小不超过 10MB
          </div>
        </template>
      </el-upload>
      <el-form :model="importForm" style="margin-top: 20px;">
        <el-form-item>
          <el-checkbox v-model="importForm.overwrite">覆盖现有配置</el-checkbox>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showImportDialog = false">取消</el-button>
        <el-button type="primary" @click="importConfigs">导入</el-button>
      </template>
    </el-dialog>

    <!-- 变更历史对话框 -->
    <el-dialog v-model="showHistoryDialog" title="配置变更历史" width="800px">
      <el-table :data="historyList" border max-height="400">
        <el-table-column prop="operated_at" label="变更时间" width="180">
          <template #default="{ row }">
            {{ formatDateTime(row.operated_at) }}
          </template>
        </el-table-column>
        <el-table-column prop="operated_by" label="操作人" width="120" />
        <el-table-column prop="change_type" label="变更类型" width="100">
          <template #default="{ row }">
            <el-tag :type="getChangeTypeTag(row.change_type)" size="small">
              {{ row.change_type }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="old_value" label="旧值" width="150" show-overflow-tooltip />
        <el-table-column prop="new_value" label="新值" width="150" show-overflow-tooltip />
        <el-table-column prop="change_reason" label="变更原因" min-width="200" />
      </el-table>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Upload,
  Download,
  Plus,
  UploadFilled
} from '@element-plus/icons-vue'
import { systemConfigApi } from '@/api/system'

// 响应式数据
const loading = ref(false)
const configList = ref([])
const pagination = reactive({
  page: 1,
  size: 20,
  total: 0
})

// 搜索表单
const searchForm = reactive({
  category: '',
  group: '',
  keyword: ''
})

// 配置表单
const configForm = reactive({
  config_key: '',
  display_name: '',
  config_category: '',
  config_type: 'string',
  config_value: '',
  group_name: '',
  description: '',
  validation_rule: '',
  sort_order: 0,
  is_required: false,
  is_readonly: false,
  is_sensitive: false
})

// 对话框状态
const showCreateDialog = ref(false)
const showImportDialog = ref(false)
const showHistoryDialog = ref(false)
const editingConfig = ref(null)
const historyList = ref([])

// 导入表单
const importForm = reactive({
  overwrite: false
})

// 表单引用
const configFormRef = ref()
const uploadRef = ref()

// 选项数据 (与文档2.2节一致)
const categoryOptions = [
  { value: 'basic', label: '基础配置' },
  { value: 'business', label: '业务配置' },
  { value: 'system', label: '系统参数' }
]

const typeOptions = [
  { value: 'string', label: '字符串' },
  { value: 'number', label: '数字' },
  { value: 'boolean', label: '布尔值' },
  { value: 'json', label: 'JSON' },
  { value: 'file', label: '文件' },
  { value: 'password', label: '密码' }
]

// 计算属性
const groupOptions = computed(() => {
  const groups = [...new Set(configList.value.map(item => item.group_name).filter(Boolean))]
  return groups.map(group => ({ value: group, label: group }))
})

const tableHeight = computed(() => {
  return window.innerHeight - 400
})

// 表单验证规则
const configFormRules = {
  config_key: [
    { required: true, message: '请输入配置键', trigger: 'blur' },
    { pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/, message: '配置键只能包含字母、数字和下划线，且以字母开头', trigger: 'blur' }
  ],
  display_name: [
    { required: true, message: '请输入显示名称', trigger: 'blur' }
  ],
  config_category: [
    { required: true, message: '请选择配置分类', trigger: 'change' }
  ],
  config_type: [
    { required: true, message: '请选择配置类型', trigger: 'change' }
  ]
}

// 方法
const loadConfigs = async () => {
  loading.value = true
  try {
    const params = {
      page: pagination.page,
      size: pagination.size,
      category: searchForm.category || undefined,
      group: searchForm.group || undefined,
      keyword: searchForm.keyword || undefined
    }
    
    const response = await systemConfigApi.getConfigs(params)
    configList.value = response.data.items
    pagination.total = response.data.total
  } catch (error) {
    ElMessage.error('加载配置列表失败')
  } finally {
    loading.value = false
  }
}

const resetSearch = () => {
  searchForm.category = ''
  searchForm.group = ''
  searchForm.keyword = ''
  pagination.page = 1
  loadConfigs()
}

const editConfig = (config) => {
  editingConfig.value = config
  Object.assign(configForm, config)
  showCreateDialog.value = true
}

const deleteConfig = async (config) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除配置项 "${config.config_key}" 吗？`,
      '删除确认',
      { type: 'warning' }
    )
    
    await systemConfigApi.deleteConfig(config.config_key)
    ElMessage.success('删除成功')
    loadConfigs()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败')
    }
  }
}

const saveConfig = async () => {
  try {
    await configFormRef.value.validate()
    
    if (editingConfig.value) {
      await systemConfigApi.updateConfig(configForm.config_key, {
        config_value: configForm.config_value,
        display_name: configForm.display_name,
        description: configForm.description,
        validation_rule: configForm.validation_rule,
        sort_order: configForm.sort_order,
        is_required: configForm.is_required,
        is_readonly: configForm.is_readonly,
        is_sensitive: configForm.is_sensitive
      })
      ElMessage.success('更新成功')
    } else {
      await systemConfigApi.createConfig(configForm)
      ElMessage.success('创建成功')
    }
    
    showCreateDialog.value = false
    loadConfigs()
  } catch (error) {
    ElMessage.error(editingConfig.value ? '更新失败' : '创建失败')
  }
}

const resetConfigForm = () => {
  editingConfig.value = null
  Object.assign(configForm, {
    config_key: '',
    display_name: '',
    config_category: '',
    config_type: 'string',
    config_value: '',
    group_name: '',
    description: '',
    validation_rule: '',
    sort_order: 0,
    is_required: false,
    is_readonly: false,
    is_sensitive: false
  })
}

const handleFileUpload = (response) => {
  if (response.success) {
    configForm.config_value = response.data.file_path
  } else {
    ElMessage.error('文件上传失败')
  }
}

const viewHistory = async (config) => {
  try {
    const response = await systemConfigApi.getConfigHistory(config.config_key)
    historyList.value = response.data
    showHistoryDialog.value = true
  } catch (error) {
    ElMessage.error('加载历史记录失败')
  }
}

const exportConfigs = async () => {
  try {
    const response = await systemConfigApi.exportConfigs({
      category: searchForm.category,
      include_sensitive: false
    })
    
    const blob = new Blob([JSON.stringify(response.data, null, 2)], {
      type: 'application/json'
    })
    const url = URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = `system_configs_${new Date().toISOString().slice(0, 10)}.json`
    link.click()
    URL.revokeObjectURL(url)
    
    ElMessage.success('导出成功')
  } catch (error) {
    ElMessage.error('导出失败')
  }
}

const handleFileChange = (file) => {
  console.log('文件选择:', file)
}

const importConfigs = async () => {
  try {
    const fileList = uploadRef.value.uploadFiles
    if (!fileList || fileList.length === 0) {
      ElMessage.warning('请选择要导入的文件')
      return
    }
    
    const file = fileList[0].raw
    const formData = new FormData()
    formData.append('file', file)
    formData.append('overwrite', importForm.overwrite.toString())
    
    const response = await systemConfigApi.importConfigs(formData)
    ElMessage.success(`导入完成：成功 ${response.data.success_count} 项，失败 ${response.data.fail_count} 项`)
    
    showImportDialog.value = false
    loadConfigs()
  } catch (error) {
    ElMessage.error('导入失败')
  }
}

// 工具函数
const getCategoryLabel = (category) => {
  const option = categoryOptions.find(opt => opt.value === category)
  return option ? option.label : category
}

const getCategoryTagType = (category) => {
  const types = {
    basic: 'primary',
    business: 'success', 
    system: 'warning'
  }
  return types[category] || ''
}

const getTypeLabel = (type) => {
  const option = typeOptions.find(opt => opt.value === type)
  return option ? option.label : type
}

const formatConfigValue = (value, type) => {
  if (!value) return '-'
  
  switch (type) {
    case 'boolean':
      return value === 'true' ? '是' : '否'
    case 'json':
      try {
        const obj = JSON.parse(value)
        return JSON.stringify(obj, null, 2)
      } catch {
        return value
      }
    default:
      return value.length > 50 ? value.substring(0, 50) + '...' : value
  }
}

const formatDateTime = (dateStr) => {
  return new Date(dateStr).toLocaleString('zh-CN')
}

const getChangeTypeTag = (type) => {
  const types = {
    create: 'success',
    update: 'primary',
    delete: 'danger'
  }
  return types[type] || ''
}

// 生命周期
onMounted(() => {
  loadConfigs()
})
</script>

<style scoped>
.system-config-page {
  padding: 20px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.page-header h2 {
  margin: 0;
  color: #303133;
}

.header-actions {
  display: flex;
  gap: 10px;
}

.search-card {
  margin-bottom: 20px;
}

.config-table-card {
  min-height: 500px;
}

.pagination-wrapper {
  margin-top: 20px;
  text-align: center;
}

.el-form-item {
  margin-bottom: 20px;
}

.el-checkbox {
  margin-right: 15px;
}
</style>